import { getSongLrc } from "@/api/content";
import type { Ref } from "vue";
import { reactive, ref } from "vue";
import { onMounted, nextTick, onBeforeUnmount } from "vue-demi";
import { useRoute } from "vue-router";

export interface LrcProp {
  time: number;
  words: string;
}

interface PlaySongProp {
  audioRef: Ref<HTMLAudioElement | null>;
  lrcContainerRef: Ref<HTMLElement | null>;
  containerRef: Ref<HTMLElement | null>;
  playRef?: HTMLElement | HTMLBodyElement;
}

export function usePlaySong({
  audioRef,
  lrcContainerRef,
  containerRef,
  playRef,
}: PlaySongProp) {
  const lrcData = ref();
  const ht = reactive({
    liH: 0,
    containerH: 0,
    maxOffset: 0,
  });
  // 高亮索引
  const currentIndex = ref(-1);
  // 移动距离
  const offsetY = ref(-1);
  // 是否在播放
  const isPlay = ref(false);
  const clickRef = ref();
  const firstLoad = ref(false);

  const { params }: any = useRoute();

  onMounted(async () => {
    // 获取歌词
    const { lrc } = await getSongLrc(params.id);
    lrcData.value = parseLrc(lrc.lyric);
    clickRef.value = playRef || document.body;
    // 获取常用高度
    nextTick(() => {
      if (lrcContainerRef.value && containerRef.value) {
        ht.liH = lrcContainerRef.value?.children[0].clientHeight;
        ht.containerH = containerRef.value?.clientHeight;
        ht.maxOffset =
          lrcContainerRef.value?.clientHeight -
          containerRef.value?.clientHeight;
      }
    });
    addEvent();
  });

  onBeforeUnmount(() => {
    removeEvent();
  });

  // 添加事件
  function addEvent() {
    // 点击播放
    clickRef.value.addEventListener("click", initPlay);
    // 初始自动播放设置
    audioRef.value?.addEventListener("play", setAutoplay);
    // 音乐播放
    audioRef.value?.addEventListener("timeupdate", setOffset);
    // 播放结束
    audioRef.value?.addEventListener("ended", resetPlay);
  }

  // 移除事件
  function removeEvent() {
    // 点击播放
    clickRef.value.removeEventListener("click", initPlay);
    // 初始自动播放设置
    audioRef.value?.removeEventListener("play", setAutoplay);
    // 音乐播放
    audioRef.value?.removeEventListener("timeupdate", setOffset);
    // 播放结束
    audioRef.value?.removeEventListener("ended", resetPlay);
  }

  // 如果是自动播放设置状态
  function setAutoplay() {
    if (!firstLoad.value) {
      firstLoad.value = true;
      isPlay.value = true;
    }
  }

  // 开始播放
  function initPlay() {
    isPlay.value = !isPlay.value;
    isPlay.value ? playSong() : stopSong();
  }

  // 播放结束
  function resetPlay() {
    isPlay.value = false;
    offsetY.value = 0;
    currentIndex.value = 0;
    stopSong();
  }

  // 歌曲播放
  function playSong() {
    audioRef.value?.play();
  }

  // 歌曲暂停
  function stopSong() {
    audioRef.value?.pause();
  }

  //处理歌词 { time: xxx, words: xxxx }
  function parseLrc(lrc: string) {
    const result: LrcProp[] = [];
    const parseStr = lrc.split("\n").filter((t) => !!t);
    for (let i = 0; i < parseStr.length; i++) {
      const strArr = parseStr[i].split("]");
      const times = strArr[0].substring(1);
      const obj = {
        time: parseTime(times),
        words: strArr[1],
      };
      result.push(obj);
    }
    return result;
  }

  // 格式化时间 xx:xxx.55
  function parseTime(time: string) {
    const strArr: string[] = time.split(":");
    return +strArr[0] * 60 + +strArr[1];
  }

  // 显示第几句歌词
  function findLrcIndex(list: LrcProp[], curTime = -1) {
    // 当前时间大于歌词显示的时间 前面一个
    const idx = list.findIndex((t) => curTime < t.time);
    if (idx !== -1) {
      return idx - 1;
    }
    return list.length - 1;
  }

  // 移动的距离
  function setOffset() {
    const index = findLrcIndex(lrcData.value, audioRef.value?.currentTime);
    currentIndex.value = index;
    let offset = index * ht.liH + ht.liH / 2 - ht.containerH / 2;
    if (offset < 0) {
      offset = 0;
    }
    if (offset > ht.maxOffset) {
      offset = ht.maxOffset;
    }
    offsetY.value = offset;
  }

  return {
    data: lrcData,
    isPlay,
    currentIndex: currentIndex,
    offsetY: offsetY,
    playSong,
    stopSong,
    setOffset,
    resetPlay,
  };
}
